Skip to content

Feature/load new lifecycle config#208

Open
NicolasFussberger wants to merge 28 commits into
eclipse-score:mainfrom
etas-contrib:feature/load-new-lifecycle-config
Open

Feature/load new lifecycle config#208
NicolasFussberger wants to merge 28 commits into
eclipse-score:mainfrom
etas-contrib:feature/load-new-lifecycle-config

Conversation

@NicolasFussberger
Copy link
Copy Markdown
Contributor

@NicolasFussberger NicolasFussberger commented May 19, 2026

  • Introduces an interface in src/launch_manager_daemon/config for loading a launch manager configuration file
  • Introduce an implementation of this interface using flatbuffer
  • Introduce unit tests for the new code

Note: The code is not actually in use yet. The python script which does the translation from the user-facing json configuration to the flatbuffer json format is not part of the PR and will be added in a follow up PR.
Furthermore, the launch manager code needs to be adapted to use the new structure.

Background:

  • In the last months we had defined a new user-facing configuration format (see src/launch_manager_daemon/config/config_schema/launch_manager.schema.json).
  • However, this new format is currently still mapped to the old configuration files (to processes / process groups). So the code is not actually reading the new configuration file

Relates To: #209

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 19, 2026

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run --lockfile_mode=error //:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
Extracting Bazel installation...
Starting local Bazel server (8.4.2) and connecting to it...
INFO: Invocation ID: eecca234-de41-4cb5-bc7a-de7292481738
Computing main repo mapping: 
Computing main repo mapping: 
Loading: 
Loading: 0 packages loaded
Loading: 0 packages loaded
Loading: 0 packages loaded
    currently loading: 
Loading: 0 packages loaded
    currently loading: 
Loading: 0 packages loaded
    currently loading: 
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)

Analyzing: target //:license-check (34 packages loaded, 10 targets configured)

Analyzing: target //:license-check (85 packages loaded, 10 targets configured)

Analyzing: target //:license-check (135 packages loaded, 2335 targets configured)

Analyzing: target //:license-check (146 packages loaded, 6118 targets configured)

Analyzing: target //:license-check (158 packages loaded, 8130 targets configured)

Analyzing: target //:license-check (158 packages loaded, 8130 targets configured)

Analyzing: target //:license-check (162 packages loaded, 10142 targets configured)

INFO: Analyzed target //:license-check (163 packages loaded, 10268 targets configured).
[12 / 16] JavaToolchainCompileClasses external/rules_java+/toolchains/platformclasspath_classes; 0s disk-cache, processwrapper-sandbox ... (2 actions running)
[14 / 16] JavaToolchainCompileBootClasspath external/rules_java+/toolchains/platformclasspath.jar; 0s disk-cache, processwrapper-sandbox
[15 / 16] Building license.check.license_check.jar (); 0s disk-cache, multiplex-worker
INFO: Found 1 target...
Target //:license.check.license_check up-to-date:
  bazel-bin/license.check.license_check
  bazel-bin/license.check.license_check.jar
INFO: Elapsed time: 21.751s, Critical Path: 2.60s
INFO: 16 processes: 12 internal, 3 processwrapper-sandbox, 1 worker.
INFO: Build completed successfully, 16 total actions
INFO: Running command line: bazel-bin/license.check.license_check ./formatted.txt <args omitted>
usage: org.eclipse.dash.licenses.cli.Main [-batch <int>] [-cd <url>]
       [-confidence <int>] [-ef <url>] [-excludeSources <sources>] [-help] [-lic
       <url>] [-project <shortname>] [-repo <url>] [-review] [-summary <file>]
       [-timeout <seconds>] [-token <token>]

@github-actions
Copy link
Copy Markdown

The created documentation from the pull request is available at: docu-html

Comment thread MODULE.bazel Outdated
Comment thread src/launch_manager_daemon/config/include/config.hpp
Comment thread src/launch_manager_daemon/config/include/config.hpp
Comment thread src/launch_manager_daemon/config/include/config.hpp Outdated
Comment thread src/launch_manager_daemon/config/include/config.hpp
Comment thread src/launch_manager_daemon/config/include/config.hpp Outdated
Comment thread src/launch_manager_daemon/config/include/config.hpp Outdated
Comment thread src/launch_manager_daemon/config/include/config.hpp
Comment thread src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp
Comment thread src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp Outdated
Comment thread src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp
Comment thread MODULE.bazel Outdated
Comment thread src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp Outdated
Comment thread src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs
@paulquiring
Copy link
Copy Markdown
Contributor

review from my side is finished.

Comment thread src/launch_manager_daemon/config/include/config.hpp Outdated
This removes the baselibs override
@NicolasFussberger NicolasFussberger marked this pull request as ready for review May 26, 2026 06:33
Comment thread src/launch_manager_daemon/config/include/config.hpp
Comment thread src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp Outdated
{
public:
/// @brief Error codes returned when configuration loading fails.
enum class Error : std::uint32_t
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to make just a ConfigError enum and not tie it into IConfigLoader

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this config loading will be the only place where this enum is used as this will be the only config loading code.
We can still move it out of the class and make if ConfigError though.
Do you see any benefit it moving it out of the class scope?

Comment thread src/launch_manager_daemon/config/include/config.hpp Outdated
Comment thread src/launch_manager_daemon/config/include/config.hpp
Comment thread src/launch_manager_daemon/config/include/config_loader.hpp Outdated
private:
void rebuildPointers() const;
std::vector<EnvironmentVariable> entries_;
mutable std::vector<const char*> pointers_;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we only ever will need to get the char* const* of the env vars would it make sense to just figure out the pointers in the envp() method and not keep track of each pointer?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pointer returned by envp() is already assembled within the envp() method implementation and not updated whenever an environment variable is added. Most likely envp() is called a single time to get the pointer for passing it into execve system call.
Probably I do not understand your comment correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I see this is needed for the backing data when you return the const char* in envp. Guess we could also just construct the vector in envp() and return the vector so that we don't need this member and don't have to worry about reconstructing it after a move?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ides was to have it directly in the format required to be used with envp() systemcall.
If we return a vector the user of this will need to do the const_cast and .data() to bring it in the right format which seems a bit inconvenient.
The vector is build directly when calling envp() so I guess it will always the valid pointers, even if the object got moved before.

Comment thread src/launch_manager_daemon/config/lm_flatcfg_generated.h
Comment thread src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp Outdated
}
}

ProcessState convertProcessState(fb::ProcessState fb_state)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to use something like this https://godbolt.org/z/TxqEW7dcE?
Don't really like how you need to hunt for the convertXYZ method, but up to you.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess its a matter of preference. Whether you search based on the type or the name.

I tend to prefer the free functions because the name of the function makes clear what is being converted.
For example vector gids is :flatbuffers::Vector<uint32_t>* which based on the type is not really obvious.

Then there is also the fact that there are a variety of return types, some return the type directly others return expected<...> if conversion may potentially fail. Although also possible with the templates, it looks a bit more straightforward with the regular functions.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea would be then that you that it's easy to separate each config type and write a converter for each type and the type definition in a single header. e.g. we have a config/details/environment.hpp that holds the Environment class definition and convert<fbsEnvironment, Environment>. In the end we can just include and use the function making it more readable.
I guess we can do the same with the convertXYZ methods?

Guess the root problem is that parseFlatbuffer is 100 lines which is pretty long for a function.
Right now I feel like this is similar to the old ConfigManager in that there is a huge piece of code that does all the converting and adding might be a pain.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe even a static method on the type struct? e.g. Environment::FromFbs()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would having the templated convert methods simplify parseFlatbuffer?. Would it not just be calling convert<A, B>(...) instead of a free function for each conversion?
How about further dividing up into methods, like e.g. parseComponents and parseRunTargets?

I don't really like having the static methods as part of the types because I think the types should be independent of flatbuffer. If we were to change from flatbuffer to json at some point, all the types could stay unchanged.
The only change would be to implement a JsonConfigLoader and instantiate the JsonConfigLoader implementation in main instead of the FlatbufferConfigLoader.

Comment thread src/control_client_lib/include/score/lcm/control_client.h Outdated
Comment thread src/control_client_lib/include/score/lcm/control_client.h Outdated
@NicolasFussberger NicolasFussberger force-pushed the feature/load-new-lifecycle-config branch from 71a4f93 to 8cd3a4b Compare May 29, 2026 05:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants